﻿using Microsoft.AspNetCore.Http;
using Qiniu.Http;
using Qiniu.IO;
using Qiniu.IO.Model;
using Qiniu.RS;
using Qiniu.Util;

namespace QYmall.Core.Common.Helper
{
    /// <summary>
    /// 七牛云帮助类
    /// </summary>
    public class QiniuHelper
    {
        /// <summary>
        /// 普通文件上传
        /// </summary>
        public static bool UploadFile(byte[] byteData, string? accessKey, string? secretKey, string? bucketName, string? fileName)
        {
            Qiniu.Common.Config.AutoZone(accessKey, bucketName, true);
            //生成(上传)凭证时需要使用此Mac
            Mac mac = new(accessKey, secretKey);
            //上传策略，参见 https://developer.qiniu.com/kodo/manual/put-policy
            PutPolicy putPolicy = new PutPolicy();
            //如果需要设置为"覆盖"上传(如果云端已有同名文件则覆盖)，请使用 SCOPE = "BUCKET:KEY"
            putPolicy.Scope = bucketName + ":" + fileName;
            //上传策略有效期(对应于生成的凭证的有效期)
            putPolicy.SetExpires(3600);
            //生成上传凭证，参见 https://developer.qiniu.com/kodo/manual/upload-token
            string jstr = putPolicy.ToJsonString();
            string token = Auth.CreateUploadToken(mac, jstr);
            FormUploader fu = new FormUploader();
            HttpResult result = fu.UploadData(byteData, fileName, token);
            if (result.Code != 200)
            {
                throw new ResponseException(result.Text);
            }
            return true;
        }

        /// <summary>
        /// 大文件分片上传
        /// </summary>
        public static async Task<bool> UploadBigFileAsync(IFormFile file, int chunkSize, string? accessKey, string? secretKey, string? bucketName, string? fileName)
        {
            Qiniu.Common.Config.AutoZone(accessKey, bucketName, true);
            // 生成(上传)凭证时需要使用此Mac
            Mac mac = new(accessKey, secretKey);

            var policy = new PutPolicy
            {
                Scope = $"{bucketName}:{fileName}",
            };
            policy.SetExpires(3600);

            string token = Auth.CreateUploadToken(mac, policy.ToJsonString());
            var target = new FormUploader();

            long uploaded = 0;
            long fileSize = file.Length;

            using (var inputStream = file.OpenReadStream())
            {
                while (uploaded < fileSize)
                {
                    int bytesToRead = (int)Math.Min(chunkSize, fileSize - uploaded);
                    byte[] buffer = new byte[bytesToRead];
                    await inputStream.ReadAsync(buffer.AsMemory(0, bytesToRead));

                    var result = target.UploadData(buffer, fileName, token);

                    if (result.Code != 200)
                    {
                        throw new ResponseException(result.Text);
                    }

                    uploaded += bytesToRead;
                }
            }

            return true;
        }

        /// <summary>
        /// 删除指定文件
        /// </summary>
        public static bool DeleteFile(string? accessKey, string? secretKey, string? bucketName, string? fileName)
        {
            Qiniu.Common.Config.AutoZone(accessKey, bucketName, true);
            //生成(上传)凭证时需要使用此Mac
            Mac mac = new Mac(accessKey, secretKey);
            BucketManager bm = new BucketManager(mac);
            HttpResult result = bm.Delete(bucketName, fileName);
            if (result.Code != 200)
            {
                return false;
            }
            return true;
        }

    }
}
